<?php

declare(strict_types=1);

namespace App\Controller\Backend\Authentication;

use App\Constants\ReturnCode;
use App\Controller\Backend\BaseController;
use App\Middleware\AuthMiddleware;
use App\Middleware\PromissionMiddleware;
use App\Model\Authentication\Admin as AdminModel;
use Hyperf\DbConnection\Db;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\DeleteMapping;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\HttpServer\Annotation\Middlewares;
use Hyperf\HttpServer\Annotation\PostMapping;
use Hyperf\HttpServer\Annotation\PutMapping;
use Hyperf\Validation\Contract\ValidatorFactoryInterface;
use Hyperf\Validation\Rule;

#[Controller]
#[Middlewares([AuthMiddleware::class, PromissionMiddleware::class])]
class AdminController extends BaseController
{
    #[Inject]
    protected ValidatorFactoryInterface $validation;

    #[Inject]
    protected AdminModel $adminModel;

    #[PostMapping(path: "create")]
    public function create()
    {
        $form = $this->request->post();

        $rules = [
            'username' => 'required|min:4|max:20',
            'mobile'   => [
                'required',
                Rule::unique('admin', 'mobile')->whereNull('deleted_at')
            ],
            'email'    => 'required|email',
            'password' => 'required|min:6|max:24',
            're_pass'  => 'required|min:6|max:24|same:password'
        ];

        $messages = [
            'username.required' => '缺少必要参数：登陆名',
            'username.min' => '请输入4-20位登陆名',
            'username.max' => '请输入4-20位登陆名',
            'mobile.required' => '缺少必要参数：手机号',
            'mobile.unique' => '手机号已存在',
            'email.required' => '缺少必要参数：手机号',
            'email.phone' => '手机号格式错误',
            'password.required' => '缺少必要参数：密码',
            'password.min' => '请输入6-24位密码',
            'password.max' => '请输入6-24位密码',
            're_pass.required' => '缺少必要参数：确认密码',
            're_pass.min' => '请输入6-24位密码',
            're_pass.max' => '请输入6-24位密码',
            're_pass.same' => '两次输入密码不一致'
        ];

        $validator = $this->validation->make($form, $rules, $messages);

        if ($validator->fails()) {
            $errorMsg = $validator->errors()->first();

            throw new \Exception($errorMsg);
        }

        Db::beginTransaction();
        try {
            $is_super = array_key_exists('is_super', $form) ? $form['is_super'] : 0;

            $this->adminModel->restoreOrCreate([
                'mobile'   => $form['mobile']
            ], [
                'username' => $form['username'],
                'password' => md5($form['password']),
                'realname' => $form['realname'] ?? '',
                'email'    => $form['email'],
                'is_super' => $is_super ? 1 : 0
            ]);

            DB::commit();
            return $this->result(ReturnCode::SUCCESS, [], '添加成功');
        } catch (\Exception $exception) {
            Db::rollBack();
            throw new \Exception($exception->getMessage());
        }
    }

    #[PutMapping(path: 'update')]
    public function update()
    {
        $id   = $this->request->query('id', 0);
        $form = $this->request->post();

        $rules = [
            'id'       => 'required|integer:strict',
            'username' => 'required|min:4|max:20',
            'mobile'   => [
                'required',
                Rule::unique('admin', 'mobile')->whereNull('deleted_at')->ignore($id)
            ],
            'email'    => 'required|email',
            'password' => 'required|min:6|max:24',
            're_pass'  => 'required|min:6|max:24|same:password'
        ];

        $messages = [
            'id.required' => '缺少必要参数：id',
            'id.integer' => 'id类型错误',
            'username.required' => '缺少必要参数：登陆名',
            'username.min' => '请输入4-20位登陆名',
            'username.max' => '请输入4-20位登陆名',
            'mobile.required' => '缺少必要参数：手机号',
            'mobile.unique' => '手机号已存在',
            'email.required' => '缺少必要参数：手机号',
            'email.phone' => '手机号格式错误',
            'password.required' => '缺少必要参数：密码',
            'password.min' => '请输入6-24位密码',
            'password.max' => '请输入6-24位密码',
            're_pass.required' => '缺少必要参数：确认密码',
            're_pass.min' => '请输入6-24位密码',
            're_pass.max' => '请输入6-24位密码',
            're_pass.same' => '两次输入密码不一致'
        ];

        $validator = $this->validation->make(['id' => $id, ...$form], $rules, $messages);

        if ($validator->fails()) {
            $errorMsg = $validator->errors()->first();

            throw new \Exception($errorMsg);
        }

        Db::beginTransaction();
        try {
            $is_super = array_key_exists('is_super', $form) ? $form['is_super'] : 0;

            $form['is_super'] = $is_super;

            $data = [
                'username' => $form['username'],
                'realname' => $form['realname'],
                'password' => md5($form['password']),
                'mobile'   => $form['mobile'],
                'email'    => $form['email'],
                'is_super' => $is_super
            ];

            $this->adminModel->where(['id' => $id])->update($data);

            DB::commit();
            return $this->result(ReturnCode::SUCCESS, [], '更新成功');
        } catch (\Exception $exception) {
            Db::rollBack();
            throw new \Exception($exception->getMessage());
        }
    }

    /**
     *  列表
     */
    #[GetMapping(path: 'list')]
    public function list()
    {
        $page = (int)$this->request->query('page', 1);
        $limit = (int)$this->request->query('limit', 15);

        $pagination = $this->adminModel->paginate($limit, [], 'page', $page);

        return $this->result(ReturnCode::SUCCESS, object_2_array($pagination));
    }

    /**
     *  删除
     */
    #[DeleteMapping(path: 'destroy')]
    public function destroy()
    {
        $id = (int)$this->request->query('id', 0);

        $rules = [ 'id' => 'required|integer:strict' ];

        $messages = [
            'id.required' => '缺少必要参数：id',
            'id.integer' => 'id类型错误'
        ];

        $validator = $this->validation->make(['id' => $id], $rules, $messages);

        if ($validator->fails()) {
            $errorMsg = $validator->errors()->first();

            return $this->result(ReturnCode::INVALID_PARAMS, [], $errorMsg);
        }

        $model = $this->adminModel->find($id);

        if (empty($model)) return $this->result(ReturnCode::INVALID_PARAMS);

        if ($model['is_super']) return $this->result(ReturnCode::NOT_AUTH, [], '不可以删除超级管理员');

        Db::beginTransaction();
        try {
            // 删除管理员
            $model->delete();
            // 删除关联角色信息
            $model->roles()->delete();

            DB::commit();
            return $this->result(ReturnCode::SUCCESS);
        } catch (\Exception $exception) {
            Db::rollBack();
            throw new \Exception($exception->getMessage());
        }
    }
}
